package com.cndcare.msc.service.impl;

import com.cndcare.msc.cloud.base.common.LayuiPageInfo;
import com.cndcare.msc.config.MyWebSocket;
import com.cndcare.msc.netty.bean.PcBean;
import com.cndcare.msc.netty.dao.jpa.PcBeanJpa;
import com.cndcare.msc.netty.dao.mapper.DangerLogMapper;
import com.cndcare.msc.netty.dao.mapper.PcMapper;
import com.cndcare.msc.netty.vo.SearchVo;
import com.cndcare.msc.service.NettyService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Transactional
@Service("nettyService")
public class NettyServiceImpl implements NettyService {
    @Autowired
    private PcBeanJpa pcBeanJpa;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private PcMapper pcMapper;
    @Autowired
    private DangerLogMapper dangerLogMapper;

    @Autowired
    private MyWebSocket myWebSocket;

    @Override
    public void dealPcByMac(PcBean pcBean) {
        if (null != pcBean) {
            String infoStatus = pcBean.getInfoStatus();
            String status = pcBean.getStatus();

            boolean infoFlag = true;
            if (StringUtils.isNotEmpty(pcBean.getRealIp()) && !pcBean.getRealIp().equals(pcBean.getIp())) {
                pcBean.setInfoStatus(PcBean.INFO_CONFLICT);
                pcBean.setStatus(PcBean.WARN);
                infoFlag = false;
            }

            if (StringUtils.isEmpty(pcBean.getAddress())
                    || StringUtils.isEmpty(pcBean.getRemark())) {
                pcBean.setInfoStatus(PcBean.UN_COMPLETE);
                pcBean.setStatus(PcBean.WARN);
                infoFlag = false;
            }
            if (infoFlag) {
                pcBean.setInfoStatus(PcBean.COMPLETE);
            }

            String redisMac = stringRedisTemplate.opsForValue().get(pcBean.getMac());
            if (StringUtils.isNotEmpty(redisMac)) {
                /**
                 * 如果为离线状态，则修改为在线状态
                 * 其余留存异常状态
                 */
                if (PcBean.OFFLINE.equals(pcBean.getStatus())
                        || (PcBean.WARN.equals(pcBean.getStatus()) && infoFlag)) {
                    pcBean.setStatus(PcBean.ONLINE);
                }
            } else {
                /**
                 * 如果为在线正常状态，则修改为离线状态
                 * 其余留存异常状态
                 */
                if (PcBean.ONLINE.equals(pcBean.getStatus())
                        || (PcBean.WARN.equals(pcBean.getStatus()) && infoFlag)) {
                    pcBean.setStatus(PcBean.OFFLINE);
                }
            }

            // 与之前一直，则不需要更新
            if (!pcBean.getStatus().equals(status) || !pcBean.getInfoStatus().equals(infoStatus)) {
                pcBean.setLevel(PcBean.levelMap.get(pcBean.getStatus()));
                pcBeanJpa.saveAndFlush(pcBean);
            }
        }
    }

    @Override
    public void handleAlarm(String mac, String type) {
        PcBean pcBean = pcBeanJpa.findByMac(mac);

        if (StringUtils.isNotEmpty(stringRedisTemplate.opsForValue().get(mac))) {
            pcBean.setStatus(PcBean.ONLINE);
            pcBean.setLevel(PcBean.levelMap.get(PcBean.ONLINE));
        } else {
            pcBean.setStatus(PcBean.OFFLINE);
            pcBean.setLevel(PcBean.levelMap.get(PcBean.OFFLINE));
        }

        pcBeanJpa.saveAndFlush(pcBean);

        dangerLogMapper.updateLog(mac, type);
    }

    @Override
    public void refreshPc() {
        List<PcBean> pcBeanList = pcBeanJpa.findAll();

        if (CollectionUtils.isNotEmpty(pcBeanList)) {
            pcBeanList.parallelStream().forEach(o -> this.dealPcByMac(o));
        }

        myWebSocket.broadcastStatus();
    }

    @Override
    public PageInfo<PcBean> listPcByParams(Integer pn, Integer pageSize, SearchVo searchVo) {
        PageHelper.startPage(pn, pageSize);

        if (StringUtils.isNotEmpty(searchVo.getStatus()) && PcBean.ALL.equals(searchVo.getStatus())) {
            searchVo.setStatus("");
        }
        List<PcBean> pcBeanList = pcMapper.listPcByParams(searchVo);

        return new LayuiPageInfo<>(pcBeanList);
    }

    @Override
    public Map<String, Object> calcPc() {
        Map<String, Object> dataMap = new HashMap<>();
        List<Map<String, Object>> mapList = pcMapper.calcPc();
        for (String key : PcBean.statsDicMap.keySet()) {
            Integer total = 0;
            for (Map<String, Object> map : mapList) {
                if (MapUtils.getString(map, "status", "").equals(key)) {
                    total = MapUtils.getInteger(map, "total", 0);
                }
            }

            dataMap.put(key, total);
        }

        return dataMap;
    }
}
